#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Symtab.h"


struct symbol_table *head, *last;

struct symbol_table *make_node()
{
	struct symbol_table *newnode;
	newnode = (struct symbol_table *)malloc(sizeof(struct symbol_table));
	if(!newnode)
	{
		printf("\nError while allocating memory for symbol table\n");
		exit(1);
	}
	newnode->next = NULL;
	newnode->ptr = NULL;
	newnode->variable_name = "";
	return newnode;
}


void add_node(struct symbol_table *node)
{
	if(head == NULL)
	{
		head = last = node;
		return;
	}
	last->next = node;
	last = node;
}

int add_object_name(struct symbol_table *node, char *oname)
{
	struct object_chain *newnode,*temp;
	newnode = (struct object_chain *)malloc(sizeof(struct object_chain));
	if(!newnode)
	{
		printf("Error allocating memory for symbol table.\n");
		exit(1);
	}
	newnode->object_name = strdup(oname);
	newnode->next = NULL;
	if(node->ptr == NULL)
	{
		node->ptr = newnode;
		return 1;
	}
	for(temp = node->ptr; temp->next != NULL; temp = temp->next); //Move to end of list
	temp->next = newnode;
	return 1;
}

int add_variable_name(struct symbol_table *node, char *vname)
{
	struct symbol_table *temp;
	for(temp = head; temp != NULL; temp = temp->next)
	{
		if(strcmp(temp->variable_name, vname) == 0 && strcmp(temp->variable_name, "") != 0)
		{
			return 0;
		}
	}
	node->variable_name = strdup(vname);
	return 1;
}

struct symbol_table * check_variable_name(char *vname)
{
	struct symbol_table *temp;
	for(temp = head; temp != NULL; temp = temp->next)
	{
		if(strcmp(temp->variable_name, vname) == 0 && strcmp(temp->variable_name, "") != 0)
		{
			return temp;
		}
	}
	return NULL;
}

struct symbol_table* return_last_node()
{
	return last;
}
		
void replicate_object_chain(struct object_chain *ptr, struct symbol_table *node)
{
	for(; ptr != NULL; ptr = ptr->next)
	{
		add_object_name(node, ptr->object_name);
	}
}

void display_table()
{
	struct symbol_table *stemp;
	struct object_chain *otemp;
	if(head == NULL)
	{
		printf("\nSymbol table not initialised.\n");
		return;
	}
	for(stemp = head; stemp != NULL; stemp = stemp->next)
	{
		printf("\nVariable Name = %s", stemp->variable_name);
		printf("\nObject Chain:\n");
		for(otemp = stemp->ptr; otemp != NULL; otemp = otemp->next)
		{
			printf("%s", otemp->object_name);
			if(otemp->next != NULL)
				printf(" -> ");
		}
	}
	printf("\n");
} 	 

void free_table()
{
	struct symbol_table *stemp;
	struct object_chain *otemp;
	
	while(head != NULL)
	{
		while(head->ptr != NULL)
		{
			otemp = head->ptr;
			head->ptr = head->ptr->next;
			free(otemp->object_name);
			free(otemp);
			otemp = NULL;
		}
		stemp = head;
		head = head->next;
		free(stemp->variable_name);
		free(stemp);
		stemp = NULL;
	}
	printf("\nMemory allocated for symbol table released.\n");
}
		

